package middleware

import (
	"blog/config"
	"blog/internal/common"
	"blog/internal/pkg/cache"
	"blog/internal/pkg/response"
	"blog/pkg/utils/jwt"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"strings"
)

const (
	GinHeaderAuthorizationKey = "Authorization"
)

func JWTMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		var tokenString = c.GetHeader(GinHeaderAuthorizationKey)
		cfg := config.GetConfig()
		if tokenString == "" {
			response.Fail(c, http.StatusForbidden, "Unauthorized")
			c.Abort()
			return
		}
		parts := strings.Split(tokenString, " ")
		if len(parts) != 2 || parts[0] != "Bearer" {
			response.Fail(c, http.StatusForbidden, "Unauthorized")
			c.Abort()
			return
		}
		token := parts[1]
		if token == "" {
			response.Fail(c, http.StatusForbidden, "Unauthorized")
			c.Abort()
			return
		}
		claims, err := jwt.ParseToken(token, cfg.Jwt.Secret)
		if err != nil {
			response.Fail(c, http.StatusForbidden, "Unauthorized")
			c.Abort()
			return
		}

		rdbtoken, err := cache.Get(c, fmt.Sprintf(common.LoginToken, claims.UserID))

		if err != nil {
			response.Fail(c, http.StatusForbidden, "Unauthorized")
			c.Abort()
			return
		}
		if rdbtoken != token {
			response.Fail(c, http.StatusForbidden, "Unauthorized")
			c.Abort()
			return
		}
		c.Set("userid", claims.UserID)
		c.Next()
	}
}
